package dao.impl.LibraryDaoImpl;

import common.util.DBUtil;
import dao.LibraryDao.BookItemDao;
import common.model.Entity.libraryEntity.BookItem;
import common.model.Entity.libraryEntity.enums.BookStatus;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.ResultSetHandler;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * BookItem 的实现类
 * 实现对 t_book_item 表的增删改查
 */
public class BookItemDaoImpl implements BookItemDao {
    private static final Logger logger = LoggerFactory.getLogger(BookItemDaoImpl.class);

    private final QueryRunner queryRunner;

    public BookItemDaoImpl() {
        this.queryRunner = new QueryRunner();
    }

    public BookItemDaoImpl(QueryRunner queryRunner) {
        this.queryRunner = queryRunner;
    }
    /**
     * 用图书isbn和图书状态来查找图书副本
     * 这部分方法用在 删除某本图书、删除图书副本、以及图书详情页的信息展示
     * @param bookIsbn
     * @param statusList
     * @return
     */
    @Override
    public Optional<List<BookItem>> findByBookIsbnAndStatus(String bookIsbn,
                                                            List<BookStatus> statusList) {
        if (statusList == null || statusList.isEmpty()) {
            return Optional.empty();
        }

        // 1. 拼占位符
        String placeholders = statusList.stream()
                .map(s -> "?")
                .collect(Collectors.joining(","));
        String sql = "SELECT * FROM t_book_item " +
                "WHERE isbn = ? AND status IN (" + placeholders + ") " +
                "ORDER BY created_at DESC";

        // 2. 参数：isbn 在前，枚举名在后
        Object[] params = new Object[statusList.size() + 1];
        params[0] = bookIsbn;
        for (int i = 0; i < statusList.size(); i++) {
            params[i + 1] = statusList.get(i).name(); // 存 "AVAILABLE" 等
        }

        try (Connection conn = DBUtil.getConnection()) {
            List<BookItem> res = queryRunner.query(
                    conn,
                    sql,
                    new BeanListHandler<>(BookItem.class),
                    params
            );
            return res == null || res.isEmpty() ? Optional.empty() : Optional.of(res);
        } catch (SQLException e) {
            logger.error("根据图书isbn和图书状态查找图书失败: isbn={}", bookIsbn, e);
            return Optional.empty();
        }
    }


    /**
     * 更新图书副本的状态 比如借出、归还、预约
     * @param conn
     * @param id     副本ID
     * @param status 新的状态
     * @return 返回布尔值，表示是否更新完成
     */
    @Override
    public boolean updateStatus(Connection conn, Long id, BookStatus status) {
        String sql = "UPDATE t_book_item SET status = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?";
        try {
            int affected = queryRunner.update(conn, sql, status.getCode(), id); // 使用 getCode()
            return affected > 0;
        } catch (SQLException e) {
            logger.error("更新图书副本状态失败: id={}, status={}", id, status, e);
            return false;
        }
    }

    /**
     * 根据图书副本 id 删除图书  用来管理员选中删除
     * @param id
     * @return 返回是否删除成功
     */
    @Override
    public boolean deleteById(Long id) {
        String sql = "DELETE FROM t_book_item WHERE id = ?";
        try (Connection conn = DBUtil.getConnection()) {
            int affected = queryRunner.update(conn, sql, id);
            return affected > 0;
        } catch (SQLException e) {
            logger.error("删除图书副本失败: id={}", id, e);
            return false;
        }
    }

    @Override
    public Optional<BookItem> findById(Long aLong) {
        return Optional.empty();
    }

    @Override
    public List<BookItem> findAll() {
        return List.of();
    }

    /**
     * 添加图书 通过 图书id 图书状态 馆藏位置
     * @param bookItem
     * @return 返回是否添加成功
     */
    @Override
    public boolean save(BookItem bookItem) {
        String sql = "INSERT INTO t_book_item (book_id, status, location) VALUES (?, ?, ?)";
        try (Connection conn = DBUtil.getConnection()) {
            int affected = queryRunner.update(conn, sql,
                    bookItem.getIsbn(),
                    bookItem.getStatus() != null ? bookItem.getStatus().getCode() : BookStatus.AVAILABLE.getCode(),
                    bookItem.getLocation());
            return affected > 0;
        } catch (SQLException e) {
            logger.error("保存图书副本失败: bookItemId={}", bookItem.getId(), e);
            return false;
        }
    }

    @Override
    public boolean update(BookItem bookItem) {
        String sql = "UPDATE t_book_item SET status = ?, location = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?";
        try (Connection conn = DBUtil.getConnection()) {
            int affected = queryRunner.update(conn, sql,
                    bookItem.getStatus().getCode(), // 使用 getCode()
                    bookItem.getLocation(),
                    bookItem.getId());
            return affected > 0;
        } catch (SQLException e) {
            logger.error("更新图书副本失败: id={}", bookItem.getId(), e);
            return false;
        }
    }

    @Override
    public long count() {
        String sql = "SELECT COUNT(*) FROM t_book_item";
        try (Connection conn = DBUtil.getConnection()) {
            return queryRunner.query(conn, sql, new ScalarHandler<>());
        } catch (SQLException e) {
            logger.error("统计图书副本数量失败", e);
            return 0;
        }
    }

}